#include<stdlib.h>
#include<stdio.h>
#include<mysql.h>
#include<math.h>
#include<string.h>
#include<time.h>
#define no_of_samples 100
int
GetRand (int min, int max)
{
  return (rand () % (max - min + 1) + min);
}

void
swap (char val1[], char val2[])
{
  char c[100];
  strcpy (c, val1);
  strcpy (val1, val2);
  strcpy (val2, c);
}

void
main (int argc, char *argv[])
{
  MYSQL *conn;
  MYSQL *conn1;
  MYSQL_RES *res1;
  MYSQL_RES *res2;
  MYSQL_RES *res3;
  MYSQL_ROW row1;
  MYSQL_ROW row2;
  MYSQL_ROW row3;
  char *attr;
  char *query3_1;
  char attrval[100][100];
  char *tablename = argv[2];
  char *tablename_sample = argv[3];
  char query1[1000] =
    "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name ='yahoo_autos' and COLUMN_NAME in ('price', 'mileage',  'sold_by','am_fm' ,'air_conditioning', 'alarm', 'anti_lock_brakes','cd_changer' , 'cd_player', 'cassette_player', 'child_safety_latch' , 'driver_air_bag', 'fog_lights' , 'heated_seats' , 'key_less_entries' , 'navigation_system', 'pass_air_bag', 'power_door_locks' , 'power_seats' , 'power_steering' , 'power_window' , 'premium_sound' , 'premium_wheels', 'reardefroster', 'rearwindowwiper' , 'roof_rack' , 'side_air_bag' , 'spoiler' , 'sunroof' , 'climate_control' , 'cruise_control' , 'power_mirrors' , 'alloy_wheels', 'steering_wheel_radio' , 'tinted_windows')";
  char *user = "root";
  char *password = "password";
  char *server = "localhost";
  char *database = argv[1];
  int i, j, k, l, flag, count;
  int m = 0;			// number of attributes
  double C = 0;			// scaling factor
  double S = 0;
  int random = 0;		// random number 
//initialize connection
  conn = mysql_init (NULL);
  conn1 = mysql_init (NULL);

  if (!mysql_real_connect
      (conn, server, user, password, database, 0, NULL, 0))
    {
      printf ("%s\n", mysql_error (conn));
      exit (1);
    }
  printf ("Query=%s\n", query1);
  if (mysql_query (conn, query1))
    {
      printf ("%s\n", mysql_error (conn));
      exit (1);
    }
//store results in res1
  res1 = mysql_store_result (conn);
  m = mysql_num_rows (res1);
// total number of attributes selected
  char attributes[m][100];
  for (j = 0; j < no_of_samples; j++)
    {
// loop to generate number of samples
      flag = 1;
      while (flag)
	{
// loop to make sure inserts atleast one tuple
	  srand (time (NULL));
	  printf ("sample number %d\n", j);
	  k = 0;
	  while (row3 = mysql_fetch_row (res1))
	    {
	      strcpy (attributes[k], row3[0]);
	      k++;
	    }
// Generate random permutaion of attributes
	  for (i = 0; i < m; i++)
	    {
	      random = GetRand (0, m - 1);
	      swap (attributes[m - i - 1], attributes[random]);
	    }

	  char query3[1000] = "select * from ";
	  //char query4[1000] = "select * from ";
	  for (i = 0; i < m; i++)
	    {
// loop to find valid tuple
	      printf ("attribute selected is : %s\n", attributes[i]);
	      char query2[50] = "select distinct ";
	      strcat (query2, attributes[i]);
	      strcat (query2, " from ");
	      strcat (query2, tablename);
	      printf ("distinct query :%s\n", query2);
	      if (mysql_query (conn, query2))
		{
		  printf ("%s\n", mysql_error (conn));
		  exit (1);
		}
	      res2 = mysql_store_result (conn);
	      k = 0;
	      while (row2 = mysql_fetch_row (res2))
		{
		  strcpy (attrval[k], row2[0]);
		  k++;

		}
	      srand (time (NULL));
	      random = GetRand (0, mysql_num_rows (res2) - 1);
	      attr = attrval[random];
	      if (i > 0)
		{
// to check query is to be appended 
		  char append[] = " and ";
		  strcat (append, attributes[i]);
		  strcat (append, "='");
		  strcat (append, attr);
		  strcat (append, "' ");
		  strcat (query3, append);
		}
	      else
		{
		  strcat (query3, tablename);
		  strcat (query3, " where ");
		  strcat (query3, attributes[i]);
		  strcat (query3, "='");
		  strcat (query3, attr);
		  strcat (query3, "' ");
		}
	      printf ("query to select rows:%s\n", query3);
	      mysql_free_result (res2);

	      if (mysql_query (conn, query3))
		{
		  printf ("%s\n", mysql_error (conn));
		  exit (1);
		}
	      res3 = mysql_store_result (conn);
	      int K = mysql_num_rows (res3);
	      printf ("rows returned are :%d\n", K);
	      mysql_free_result (res3);
	      if (K < 1)
// if underflow
		break;
	      else if (K > 500)
//if overflow
		continue;
	      else
		{		//if valid
		  C = pow (2, m);	// total number of possible tuples
		  S = (1 / pow (2, (i + 1))) * C;	// possile tuples after i iterations
		  printf ("%lf\n", C);
		  printf ("%lf\n", S);
		  srand (time (NULL));
		  random = GetRand (0, C);
		  printf ("random number selected is:%d\n", random);
		  if (random >= S)
		    {		// if randomly selected values is between and S and C
		      char name[100][100];
		      srand (0);
		      random = GetRand (1, K);
		      count = 1;
		      if (mysql_query (conn, query3))
			{
			  printf ("%s\n", mysql_error (conn));
			  exit (1);
			}
//select random tuple from set of top k tuples
		      res3 = mysql_store_result (conn);
		      while (row3 = mysql_fetch_row (res3))
			{
			  if (count == random)
			    {
			      for (k = 0; k < m + 3; k++)
				{
				  strcpy (name[k], row3[k]);
				}
			    }
			  count++;
			}
		      if (!mysql_real_connect
			  (conn1, server, user, password, database, 0, NULL,
			   0))
			{
			  printf ("%s\n", mysql_error (conn));
			  exit (1);
			}
		      char query5[1000] = "insert into ";
		      strcat (query5, tablename_sample);
		      strcat (query5, " values('");
		      for (l = 0; l < m + 3; l++)
			{	// total number of atrributes in table are m+3 where m is attributes selected for sampling
			  strcat (query5, name[l]);
			  if (l < m + 3 - 1)
			    strcat (query5, "','");
			}
		      strcat (query5, "')");
		      printf (" insert query is :%s\n", query5);
		      if (mysql_query (conn1, query5))
			{
			  printf ("%s\n", mysql_error (conn));
			  exit (1);
			}
		      printf ("Row is inserted with query:%s\n", query5);
		      flag = 0;
		    }
		  else
		    {
		      printf ("no row inserted\n");
		      break;
		    }

		}
	      mysql_free_result (res3);
	      break;
	    }
// end of loop to select a random valid tuple
	  if (flag == 0)
	    break;
	}			// loop to make sure atleast one tuple is selected
    }				// end of sample loop to generate sample
  mysql_close (conn);
  mysql_close (conn1);
}
